using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace ChosTIS
{
    public class InventoryManager : Singleton<InventoryManager>
    {
        [Header("Current Tetris Item Grid")]
        public TetrisItemGrid selectedTetrisItemGrid;
        [Header("Tetris Item Details Data")]
        public ItemDataList_SO itemDataList_SO;
        [Header("Tetris Item Points Set Data")]
        public TetrisItemPointSet_SO tetrisItemPointSet_SO;
        [Header("Depository")]
        public TetrisItemGrid depositoryGrid;
        [Header("Components")]
        [SerializeField] private Canvas canvas;
        [SerializeField] private InventoryHighlight inventoryHighlight;
        [SerializeField] private TetrisItemGhost tetrisItemGhost;
        [SerializeField] private RightClickMenuPanel rightClickMenuPanel;
        [SerializeField] private Text totalValueText;
        public TetrisItem selectedTetrisItem;
        public Vector2Int tileGridOriginPosition;

        private TetrisItem overlapItem;
        private Vector2Int oldPosition;
        private int selectedItemIndex;
        private float updateTimer = 0f;
        private const float UPDATE_INTERVAL = 1f;

        private void Update()
        {
            //[Debug] Dynamically add items randomly
            if (Input.GetKeyDown(KeyCode.Q))
            {
                if (selectedItemIndex >= itemDataList_SO.itemDetailsList.Count)
                {
                    selectedItemIndex = 0;
                }
                if (selectedTetrisItem != null)
                {
                    Destroy(selectedTetrisItem.gameObject);
                    selectedTetrisItem = null;
                }
                CreateItemInOrder(selectedItemIndex);
                ++selectedItemIndex;
            }

            //Rotating item
            if (Input.GetKeyDown(KeyCode.R))
            {
                oldPosition = new();
                RotateItemGhost();
            }

            //Pick up item UI location
            if (selectedTetrisItem) selectedTetrisItem.transform.position = Input.mousePosition;

            if (Input.GetMouseButtonDown(0))
            {
                TetrisItemGrid tetrisItemGrid = GetGridUnderMouse();
                if (tetrisItemGrid != null)
                {
                    //Gets the grid coordinates of the current mouse position in the grid and prints it to the console
                    Vector2Int tileGridOriginPosition = GetTileGridOriginPosition(tetrisItemGrid);
                    if (selectedTetrisItem == null)
                    {
                        return;
                    }
                    else
                    {
                        PlaceItem(tileGridOriginPosition, tetrisItemGrid);
                        selectedItemIndex = 0;
                    }

                }

            }

            HandleHighlight(selectedTetrisItemGrid != null);

            // 更新总价值显示
            updateTimer += Time.deltaTime;
            if (updateTimer >= UPDATE_INTERVAL)
            {
                updateTimer = 0f;
                UpdateTotalValue();
            }
        }

        /// <summary>
        /// Gets Tetris's point coordinates
        /// </summary>
        /// <param name="shape"></param>
        /// <returns></returns>
        public List<Vector2Int> GetTetrisPieceShapePos(TetrisPieceShape shape)
        {
            return tetrisItemPointSet_SO.TetrisPieceShapeList[(int)shape].points;
        }

        private void RotateItemGhost()
        {
            if (tetrisItemGhost.ItemDetails == null) return;
            tetrisItemGhost.Rotate();
        }

        /// <summary>
        /// Gets the origin grid coordinates of TetrisItemGhost, and returns the mouse location grid coordinates if the item is not picked up
        /// </summary>
        /// <returns></returns>
        public Vector2Int GetGhostTileGridOriginPosition()
        {
            if (selectedTetrisItemGrid == null) return new Vector2Int();
            Vector2 origin = Input.mousePosition;
            Vector2Int tileGridPosition = selectedTetrisItemGrid.GetTileGridPosition(origin);
            if (tetrisItemGhost.ItemDetails != null)
            {
                int offsetX = Mathf.FloorToInt((tetrisItemGhost.WIDTH - 1) / 2);
                int offsetY = Mathf.FloorToInt((tetrisItemGhost.HEIGHT - 1) / 2);
                tileGridPosition.x -= offsetX;
                tileGridPosition.y -= offsetY;
            }
            return tileGridPosition;
        }

        /// <summary>
        /// Gets the origin grid coordinates of the TetrisItem and returns the mouse location grid coordinates if the item is not picked up
        /// </summary>
        /// <returns></returns>
        private Vector2Int GetTileGridOriginPosition(TetrisItemGrid tetrisItemGrid)
        {
            Vector2 origin = Input.mousePosition;
            if (selectedTetrisItem != null)
            {
                origin.x -= (selectedTetrisItem.WIDTH - 1) * tetrisItemGrid.TileSizeWidth / 2;
                origin.y += (selectedTetrisItem.HEIGHT - 1) * tetrisItemGrid.TileSizeHeight / 2;
            }
            Vector2Int tileGridPosition = tetrisItemGrid.GetTileGridPosition(origin);
            return tileGridPosition;
        }

        private void HandleHighlight(bool isShow)
        {
            Vector2Int positionOnGrid = GetGhostTileGridOriginPosition();
            if (oldPosition == positionOnGrid) return;
            oldPosition = positionOnGrid;
            if (tetrisItemGhost.OnDragging && isShow)
            {
                inventoryHighlight.Show(true);
                inventoryHighlight.UpdateShapeHighlight(tetrisItemGhost, positionOnGrid, selectedTetrisItemGrid);
                inventoryHighlight.SetParent(selectedTetrisItemGrid);
                inventoryHighlight.SetPosition(selectedTetrisItemGrid,
                tetrisItemGhost.selectedTetrisItem,
                positionOnGrid.x, positionOnGrid.y);
            }
            else
            {
                inventoryHighlight.Show(false);
            }
        }

        /// <summary>
        /// Drag Drop to Place Tetris Item
        /// </summary>
        /// <param name="tileGridOriginPosition"></param>
        public void PlaceGhostItem(Vector2Int tileGridOriginPosition, TetrisItem tetrisItem, TetrisItemGrid targetGrid, InventorySlot fromSlot)
        {
            if (targetGrid == null) return;
            bool isDone = targetGrid.TryPlaceTetrisItem(tetrisItem, tileGridOriginPosition.x, tileGridOriginPosition.y);
            Debug.Log($"[调试] PlaceGhostItem后 {targetGrid.name}.OwnerItemDic.Count={targetGrid.OwnerItemDic.Count}");
            StartCoroutine(PlaceChildItem(tetrisItem, targetGrid, fromSlot));
        }

        /// <summary>
        /// Programmatic place item
        /// </summary>
        /// <param name="tileGridOriginPosition"></param>
        private void PlaceItem(Vector2Int tileGridOriginPosition, IInventoryContainer container)
        {
            if (container == null) return;
            TetrisItemGrid tetrisItemGrid = container as TetrisItemGrid;
            bool isDone = tetrisItemGrid.TryPlaceTetrisItem(
                ref selectedTetrisItem,
                tileGridOriginPosition.x, 
                tileGridOriginPosition.y, 
                ref overlapItem);
            Debug.Log($"[调试] PlaceItem后 {tetrisItemGrid.name}.OwnerItemDic.Count={tetrisItemGrid.OwnerItemDic.Count}");
            overlapItem = null;
        }

        /// <summary>
        /// Place sub items in the activity backpack, nested items are not allowed in inventory
        /// </summary>
        /// <param name="parentItem"></param>
        /// <param name="targetGrid"></param>
        /// <returns></returns>
        private IEnumerator PlaceChildItem(TetrisItem parentItem, TetrisItemGrid targetGrid, InventorySlot fromSlot)
        {
            if (!parentItem.TryGetItemComponent<GridPanelComponent>(out GridPanelComponent gridPanel)) yield break;
            yield return null;
            if (gridPanel.TetrisItemGrids.Count > 0)
            {
                foreach (TetrisItemGrid fromGrid in gridPanel.TetrisItemGrids)
                {
                    if (fromGrid.OwnerItemDic.Count > 0)
                    {
                        Dictionary<int, TetrisItem> _ownerItemDic = new(fromGrid.OwnerItemDic);
                        foreach (TetrisItem item in _ownerItemDic.Values)
                        {
                            // 保持物品在容器内，只更新其父容器引用
                            item.CurrentInventoryContainer = targetGrid;
                            item.SetItemData(item.GetInstanceID());
                            yield return null;
                        }
                    }
                    yield return null;
                }
            }
        }

        private void ResetParent(TetrisItem parentItem, InventorySlot fromSlot)
        {
            if (parentItem.CurrentInventoryContainer as InventorySlot == null)
            {
                fromSlot.PlaceTetrisItem(parentItem);
                parentItem.CurrentInventoryContainer = fromSlot;
                parentItem.SetItemData(parentItem.GetInstanceID());
            }
        }

        public StackableComponent CreateNewStackableItem(int itemID)
        {
            if (selectedTetrisItem) return null;
            selectedTetrisItem = Instantiate(itemDataList_SO.GetItemDetailsByID(itemID).uiPrefab).GetComponent<TetrisItem>();
            selectedTetrisItem.transform.SetParent(canvas.transform, false);
            selectedTetrisItem.transform.SetAsLastSibling();
            selectedTetrisItem.GetComponent<Image>().raycastTarget = false;
            TetrisItemGrid tetrisItemGrid = rightClickMenuPanel._currentItem.GetComponentInParent<TetrisItemGrid>();
            selectedTetrisItem.Initialize(itemDataList_SO.GetItemDetailsByID(itemID), null, tetrisItemGrid);
            selectedTetrisItem.TryGetItemComponent<StackableComponent>(out var stackableComponent);
            return stackableComponent;
        }

        private void CreateItemInOrder(int selectedItemIndex)
        {
            if (selectedTetrisItem) return;

            // 确保有选中的格子
            if (selectedTetrisItemGrid == null)
            {
                selectedTetrisItemGrid = GetGridUnderMouse();
                if (selectedTetrisItemGrid == null)
                {
                    Debug.LogWarning("No grid selected for item creation");
                    return;
                }
            }

            selectedTetrisItem = Instantiate(itemDataList_SO.GetItemDetailsByIndex(selectedItemIndex).uiPrefab).GetComponent<TetrisItem>();
            selectedTetrisItem.transform.SetParent(canvas.transform, false);
            selectedTetrisItem.transform.SetAsLastSibling();
            selectedTetrisItem.GetComponent<Image>().raycastTarget = false;
            selectedTetrisItem.Initialize(itemDataList_SO.itemDetailsList[selectedItemIndex], null, selectedTetrisItemGrid);
        }

        private TetrisItemGrid GetGridUnderMouse()
        {
            PointerEventData eventData = new PointerEventData(EventSystem.current)
            {
                position = Input.mousePosition
            };

            List<RaycastResult> results = new List<RaycastResult>();
            EventSystem.current.RaycastAll(eventData, results);

            foreach (RaycastResult result in results)
            {
                if (result.gameObject.CompareTag("TetrisGrid"))
                {
                    return result.gameObject.GetComponent<TetrisItemGrid>();
                }
            }

            return null;
        }

        private void UpdateTotalValue()
        {
            if (totalValueText == null) return;

            int totalValue = CalculateTotalValue();
            totalValueText.text = $"Total Value: {totalValue}";
        }

        private int CalculateTotalValue()
        {
            int totalValue = 0;
            var visited = new HashSet<int>();
            // 统计所有TetrisItemGrid
            var allGrids = FindObjectsOfType<TetrisItemGrid>();
            foreach (var grid in allGrids)
            {
                if (grid == depositoryGrid) continue;
                foreach (var item in grid.OwnerItemDic.Values)
                {
                    totalValue += GetItemAndChildrenValue(item, visited);
                }
            }
            // 统计所有装备栏（InventorySlot）上的物品
            var allSlots = FindObjectsOfType<InventorySlot>();
            foreach (var slot in allSlots)
            {
                if (slot.RelatedTetrisItem != null)
                {
                    totalValue += GetItemAndChildrenValue(slot.RelatedTetrisItem, visited);
                }
            }
            return totalValue;
        }

        // 递归统计物品及其所有子物品的价值，避免重复统计
        private int GetItemAndChildrenValue(TetrisItem item, HashSet<int> visited)
        {
            if (item == null || item.ItemDetails == null) return 0;
            if (!visited.Add(item.GetInstanceID())) return 0; // 已统计过则跳过
            int value = item.ItemDetails.itemPrice;
            // 判断是否为容器
            if (item.TryGetItemComponent<GridPanelComponent>(out var gridPanel))
            {
                foreach (var childGrid in gridPanel.TetrisItemGrids)
                {
                    foreach (var childItem in childGrid.OwnerItemDic.Values)
                    {
                        value += GetItemAndChildrenValue(childItem, visited);
                    }
                }
            }
            return value;
        }

        // 全局物品移动日志
        private void LogItemMove(TetrisItem item, string from, string to, string opType = "移动")
        {
            Debug.Log($"[{opType}] {item.ItemDetails.itemName} (旋转:{item.Rotated}) 从{from} -> {to}");
        }

        // 自动整理按钮：Get
        public void OnGetButtonClick()
        {
            Debug.Log("[Get] 自动整理开始");
            // 1. 全部转移到Depository
            MoveAllItemsToDepository();
            Debug.Log($"[Get] 转移后depository物品数: {depositoryGrid.OwnerItemDic.Count}");

            // 2. 优先装备所有容器（有GridPanelComponent的物品）
            var containers = new List<TetrisItem>(depositoryGrid.OwnerItemDic.Values);
            foreach (var item in containers)
            {
                if (item != null && item.ItemDetails != null && item.gameObject != null)
                {
                    if (item.TryGetItemComponent<GridPanelComponent>(out _))
                    {
                        TryEquipContainer(item);
                    }
                }
            }

            // 3. 多轮递归尝试把所有物品放到玩家身上，直到没有物品能再被放下
            bool moved;
            int round = 0;
            do
            {
                moved = false;
                var allItems = new List<TetrisItem>(depositoryGrid.OwnerItemDic.Values);
                // 过滤掉已被销毁或无效的物品
                allItems.RemoveAll(item => item == null || item.ItemDetails == null || item.gameObject == null);
                allItems.Sort((a, b) => b.ItemDetails.itemPrice.CompareTo(a.ItemDetails.itemPrice));
                foreach (var item in allItems)
                {
                    if (TryPlaceItemToPlayerInventory(item))
                    {
                        moved = true;
                        Debug.Log($"[Get][Round{round}] 放置物品: {item.ItemDetails.itemName} (旋转:{item.Rotated})");
                    }
                }
                round++;
            } while (moved);
            Debug.Log($"[Get] 整理结束，depository剩余物品数: {depositoryGrid.OwnerItemDic.Count}");
        }

        // 优先装备容器到装备栏/背包槽
        private bool TryEquipContainer(TetrisItem container)
        {
            var allSlots = FindObjectsOfType<InventorySlot>();
            foreach (var slot in allSlots)
            {
                if (slot.RelatedTetrisItem == null && slot.GetInventorySlotType() == container.ItemDetails.inventorySlotType)
                {
                    Debug.Log($"[装备] {container.ItemDetails.itemName} (旋转:{container.Rotated}) -> 槽:{slot.GetInventorySlotType()}");
                    slot.PlaceTetrisItem(container);
                    LogItemMove(container, $"Depository", $"Slot:{slot.GetInventorySlotType()}", "装备");
                    depositoryGrid.OwnerItemDic.Remove(container.GetInstanceID());
                    return true;
                }
            }
            return false;
        }

        // 辅助方法：尝试将物品放入玩家身上（背包、装备栏等），允许嵌套
        private bool TryPlaceItemToPlayerInventory(TetrisItem item)
        {
            if (item == null || item.ItemDetails == null || item.gameObject == null)
                return false;
            var allGrids = FindObjectsOfType<TetrisItemGrid>();
            foreach (var grid in allGrids)
            {
                if (grid == depositoryGrid) continue;
                for (int x = 0; x < grid.gridSizeWidth; x++)
                {
                    for (int y = 0; y < grid.gridSizeHeight; y++)
                    {
                        // 先尝试当前朝向
                        if (grid.TryPlaceTetrisItem(item, x, y))
                        {
                            Debug.Log($"[放置] {item.ItemDetails.itemName} (旋转:{item.Rotated}) 从depository -> {grid.name} ({x},{y})");
                            LogItemMove(item, $"Depository", $"Grid:{grid.name}({x},{y})");
                            depositoryGrid.OwnerItemDic.Remove(item.GetInstanceID());
                            return true;
                        }
                        // 再尝试旋转
                        item.Rotated = !item.Rotated;
                        if (grid.TryPlaceTetrisItem(item, x, y))
                        {
                            Debug.Log($"[放置] {item.ItemDetails.itemName} (旋转:{item.Rotated}) [旋转后] 从depository -> {grid.name} ({x},{y})");
                            LogItemMove(item, $"Depository", $"Grid:{grid.name}({x},{y})", "旋转后放置");
                            depositoryGrid.OwnerItemDic.Remove(item.GetInstanceID());
                            return true;
                        }
                        // 恢复原状态
                        item.Rotated = !item.Rotated;
                    }
                }
            }
            // 也可以尝试放入装备栏等
            var allSlots = FindObjectsOfType<InventorySlot>();
            foreach (var slot in allSlots)
            {
                if (slot.RelatedTetrisItem == null)
                {
                    Debug.Log($"[放置] {item.ItemDetails.itemName} (旋转:{item.Rotated}) 从depository -> 装备槽:{slot.GetInventorySlotType()}");
                    LogItemMove(item, $"Depository", $"Slot:{slot.GetInventorySlotType()}", "装备");
                    slot.RelatedTetrisItem = item;
                    depositoryGrid.OwnerItemDic.Remove(item.GetInstanceID());
                    return true;
                }
            }
            return false;
        }

        // 自动整理按钮：Put
        public void OnPutButtonClick()
        {
            // 1. 全部转移到Depository
            MoveAllItemsToDepository();

            // 2. 按类型分组、体积排序
            var allItems = new List<TetrisItem>(depositoryGrid.OwnerItemDic.Values);
            allItems.Sort((a, b) =>
            {
                int typeCompare = a.ItemDetails.inventorySlotType.CompareTo(b.ItemDetails.inventorySlotType);
                if (typeCompare != 0) return typeCompare;
                return (b.WIDTH * b.HEIGHT).CompareTo(a.WIDTH * a.HEIGHT);
            });

            // 3. 俄罗斯方块式排列
            ArrangeItemsTetrisStyle(allItems);
        }

        // 辅助方法：将所有非Depository区域物品转移到depositoryGrid
        private void MoveAllItemsToDepository()
        {
            // 移除清空depositoryGrid，避免丢失手动放入的物品
            // depositoryGrid.ClearAllItems();
            var allGrids = FindObjectsOfType<TetrisItemGrid>();
            var failedItems = new List<TetrisItem>();
            foreach (var grid in allGrids)
            {
                var id = grid.GetComponent<PersistentGridIdentification>();
                if (id != null && id.persistentGridType == PersistentGridType.Depository)
                    continue; // 跳过仓库
                var items = new List<TetrisItem>(grid.OwnerItemDic.Values);
                foreach (var item in items)
                {
                    // 先移除
                    grid.RemoveTetrisItem(item, item.onGridPositionX, item.onGridPositionY, item.RotationOffset, item.TetrisPieceShapePos);
                    // 再放入depository
                    bool placed = false;
                    for (int x = 0; x < depositoryGrid.gridSizeWidth; x++)
                    {
                        for (int y = 0; y < depositoryGrid.gridSizeHeight; y++)
                        {
                            if (depositoryGrid.TryPlaceTetrisItem(item, x, y))
                            {
                                placed = true;
                                LogItemMove(item, $"{grid.name}", $"Depository({x},{y})", "转移");
                                break;
                            }
                        }
                        if (placed) break;
                    }
                    if (!placed)
                    {
                        failedItems.Add(item);
                        Debug.LogWarning($"[MoveAllItemsToDepository] 物品 {item.ItemDetails.itemName} 无法放入depository，已记录");
                        Destroy(item.gameObject); // 只销毁彻底失败的物品
                    }
                }
            }
            // 也可以遍历InventorySlot等其它容器
            var allSlots = FindObjectsOfType<InventorySlot>();
            foreach (var slot in allSlots)
            {
                if (slot.RelatedTetrisItem != null)
                {
                    var item = slot.RelatedTetrisItem;
                    slot.RemoveTetrisItem();
                    bool placed = false;
                    for (int x = 0; x < depositoryGrid.gridSizeWidth; x++)
                    {
                        for (int y = 0; y < depositoryGrid.gridSizeHeight; y++)
                        {
                            if (depositoryGrid.TryPlaceTetrisItem(item, x, y))
                            {
                                placed = true;
                                LogItemMove(item, $"Slot:{slot.GetInventorySlotType()}", $"Depository({x},{y})", "转移");
                                break;
                            }
                        }
                        if (placed) break;
                    }
                    if (!placed)
                    {
                        failedItems.Add(item);
                        Debug.LogWarning($"[MoveAllItemsToDepository] 物品 {item.ItemDetails.itemName} 无法放入depository，已记录");
                        Destroy(item.gameObject); // 只销毁彻底失败的物品
                    }
                }
            }
            if (failedItems.Count > 0)
            {
                Debug.LogError($"[MoveAllItemsToDepository] 有{failedItems.Count}个物品未能放入depository，请检查格子大小或逻辑！");
            }
        }

        // 辅助方法：俄罗斯方块式排列（简单贪心，后续可优化）
        private void ArrangeItemsTetrisStyle(List<TetrisItem> items)
        {
            // 彻底清空depositoryGrid
            depositoryGrid.ClearAllItems();
            // 依次尝试从左上到右下排列
            foreach (var item in items)
            {
                bool placed = false;
                for (int x = 0; x < depositoryGrid.gridSizeWidth; x++)
                {
                    for (int y = 0; y < depositoryGrid.gridSizeHeight; y++)
                    {
                        if (depositoryGrid.TryPlaceTetrisItem(item, x, y))
                        {
                            placed = true;
                            break;
                        }
                    }
                    if (placed) break;
                }
            }
        }
    }
}